package hw2.jpa.spring.mf.wrapper;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.persistence.Embeddable;

@Embeddable
public class MfDate implements Serializable {

	private static final long serialVersionUID = 1L;

	private GregorianCalendar _base;

	public MfDate() {
	}

	public MfDate(int year, int month, int day) {
		initialize(new GregorianCalendar(year, month - 1, day));
	}

	public MfDate(GregorianCalendar gregorianCalendar) {
		initialize(gregorianCalendar);
	}

	public MfDate(java.sql.Date sqlDate) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTimeInMillis(sqlDate.getTime());
		initialize(calendar);
	}

	private void initialize(GregorianCalendar gregorianCalendar) {
		_base = trimToDays(gregorianCalendar);
	}

	private GregorianCalendar trimToDays(GregorianCalendar gregorianCalendar) {
		GregorianCalendar calendar = gregorianCalendar;
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar;
	}

	public GregorianCalendar getCalendar() {
		return _base;
	}

	public GregorianCalendar get_base() {
		return _base;
	}

	public void set_base(GregorianCalendar _base) {
		this._base = _base;
	}

	public Date getTime() {
		return _base.getTime();
	}

	public int getYear() {
		return _base.get(Calendar.YEAR);
	}

	public int getMonth() {
		return _base.get(Calendar.MONTH);
	}

	public int getDayOfMonth() {
		return _base.get(Calendar.DAY_OF_MONTH);
	}

	public boolean after(MfDate mfDate) {
		return getTime().after(mfDate.getTime());
	}

	public boolean before(MfDate mfDate) {
		return getTime().before(mfDate.getTime());
	}

	public int compareTo(Object dateObject) {
		MfDate otherDate = (MfDate) dateObject;
		return getTime().compareTo(otherDate.getTime());
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((_base == null) ? 0 : _base.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof MfDate)) {
			return false;
		}
		MfDate other = (MfDate) obj;
		if (_base == null) {
			if (other._base != null) {
				return false;
			}
		} else if (!_base.equals(other._base)) {
			return false;
		}
		return true;
	}

	public MfDate addDays(int days) {
		return new MfDate(new GregorianCalendar(getYear(), getMonth(),
				getDayOfMonth() + days));
	}

	public MfDate minusDays(int days) {
		return addDays(-days);
	}

	public java.sql.Date toSqlDate() {
		return new java.sql.Date(_base.getTimeInMillis());
	}

}
